package net.wicp.tams.common.tracer.instrumentation.impl;

import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import com.google.common.io.Resources;

import javassist.CtClass;
import javassist.CtMethod;
import net.wicp.tams.commons.Result;

public class EnhanceApacheHttpClient extends EnhanceSuperClass {

	public EnhanceApacheHttpClient(String className) {
		super(className, "org.apache.http.client.HttpClient");
	}

	@Override
	public Result enhance(CtMethod method, String newMethodName) {
		try {
			String hostParameter = "null";
			String requestParameter = "null";
			String requestUriParameter = "null";
			String handlerParameter = "null";
			CtClass[] parameterTypes = method.getParameterTypes();
			for (int i = 0; i < parameterTypes.length; i++) {
				if (parameterTypes[i].subtypeOf(pool.get("org.apache.http.HttpHost"))) {
					hostParameter = "$" + (i + 1);
				} else if (parameterTypes[i].subtypeOf(pool.get("org.apache.http.client.methods.HttpUriRequest"))) {
					requestParameter = "$" + (i + 1);
					requestUriParameter = "$" + (i + 1);
				} else if (parameterTypes[i].subtypeOf(pool.get("org.apache.http.HttpRequest"))) {
					requestParameter = "$" + (i + 1);
				}
			}

			final String source = Resources.toString(
					Resources.getResource(getClass(), "/enhance/HttpClient_execute.javassist"),
					Charset.forName("utf-8"));
			pool.importPackage("java.net");
			pool.importPackage("org.apache.http");
			pool.importPackage("org.apache.http.client.methods");
			String body = source.replace("%HTTP_HOST_PARAM%", hostParameter)
					.replace("%HTTP_REQUEST_PARAM%", requestParameter)
					.replace("%HTTP_REQUEST_URI_PARAM%", requestUriParameter)
					.replace("%RESPONSE_HANDLER_PARAM%", handlerParameter);
			method.setBody(body, "this", newMethodName);
		} catch (Exception e) {
			return Result.getError("加强错误：" + e.getMessage());
		}

		return Result.getSuc();
	}

	@Override
	public List<CtMethod> findEnhanceMethods(CtClass cc) {
		List<CtMethod> retlist = new ArrayList<>();
		for (CtMethod method : cc.getDeclaredMethods()) {
			if ("execute".equals(method.getName()) && !Modifier.isAbstract(method.getModifiers())) {
				retlist.add(method);
			}

		}
		return retlist;
	}

}
